/*
 * @Author: hyq
 * @LastEditors: hyq
 * @Description: http request
 * @Date: 2023-12-05 11:07:27
 */
import RequestSuccessCallbackResult = UniApp.RequestSuccessCallbackResult
import RequestOptions = UniApp.RequestOptions
import GeneralCallbackResult = UniApp.GeneralCallbackResult
import {
  clearStorage,
  switchTab,
  uniModal,
  uniToast,
  navigateTo
} from '@/utils'

const host = import.meta.env.VITE_BASE_URL

export default function HttpRequest<T>(opts: {
  url: string
  method: string
  header?: any
  data: object
  hideToast?: boolean
  clear?: boolean
  responseType?: string
  file?: File
}): Promise<{
  success: boolean
  code: string
  message: string
  data: T
  token?: string
  result?: number
  mobilePhone?: string
  openId?: string
  templateIds?: any
  applied?: boolean
  localExist?: boolean
}> {
  const { url, data, header, method, clear = true, responseType } = opts

  const params = filterNull(data)
  const token = uni.getStorageSync('Token')
  const XIToken = uni.getStorageSync('XI-Token')
  const uri = host + url
  console.log(uri)
  return new Promise((resolve, reject) => {
    uni.request({
      url: uri,
      data: params,
      header: {
        token: token,
        'XI-Token': XIToken,
        ...header
      },
      timeout: 60000,
      responseType: responseType,
      method: method,
      async success(res: RequestSuccessCallbackResult) {
        uni.hideLoading()
        const data: any = res.data
        //所有没有成功的错误返回
        if (data.status >= 500) {
          await uniToast('网络错误，请稍后再试')
          reject(data)
          return
        }

        if (res.statusCode !== 200) {
          await uniToast('网络错误，请稍后再试')
          resolve(data)
          return
        }

        if (data.success) {
          resolve(data)
        } else if (data.code === '0109000') {
          await uniToast('登录信息已过期，请重新登录')
          setTimeout(() => {
            clear && clearStorage()
            resolve(data)
            // clear && switchTab('/pages/index/index')
            clear && navigateTo('/pages/login/login')
          }, 1500)
        } else {
          const message = getErrorMessage(data.message)
          if (data.code === '000003') {
            resolve(data)
          } else {
            if (data.message?.length > 6) {
              await uniModal({
                showCancel: false,
                title: '提示',
                content: message
              })
            } else {
              !opts.hideToast && (await uniToast(message || '服务异常'))
            }
            resolve(data)
          }
        }
      },
      async fail(res: GeneralCallbackResult) {
        uni.hideLoading()
        console.log(res)

        setTimeout(async () => {
          await uniToast('连接超时，请检查您的网络')
        })
        reject({
          success: false,
          code: '000',
          message: '连接超时，请检查您的网络'
        })
      }
    } as RequestOptions)
  })
}

/**
 * 获取错误的信息
 * @param dataMessaqge H
 * @returns
 */
function getErrorMessage(dataMessaqge) {
  if (!dataMessaqge) {
    return ''
  }
  const isHas = dataMessaqge.indexOf('内部错误') > -1 ? true : false
  const message = isHas ? '网络错误，请稍后再试' : dataMessaqge || ''
  return message
}

function filterNull(o: any) {
  // 过滤空参数
  for (const key in o) {
    const value: any = o[key]
    if (toType(o[key]) !== 'boolean' && value !== 0 && !value) {
      delete o[key]
    }
    if (toType(o[key]) === 'string') {
      o[key] = o[key].trim()
      if (o[key].length === 0) {
        delete o[key]
      }
    }
  }
  return o
}

function toType(obj: any) {
  // 判断元素类型
  const reg = /\s([a-zA-Z]+)/
  const originType = {}.toString.call(obj).match(reg)
  const type: any = originType && originType[1]
  return type.toLowerCase()
}
